using System;
using System.IO;
using System.Xml;
using System.Drawing;
using System.Windows.Forms;

namespace needle.UI.Controls.Flat.Windows.Forms
{
	public abstract class TabGroupBase : IDisposable
	{
		#region Nested types
		
		public enum NotifyCode
	    {
	        StyleChanged,
            ProminentChanged,
            MinimumSizeChanged,
            ResizeBarVectorChanged,
	        ResizeBarColorChanged,
	        DisplayTabMode,
	        ImageListChanging,
	        ImageListChanged
	    }

		#endregion

		protected static int mcount = 0;
	    
	    protected int munique;
	    protected object mtag;
        protected Size mminSize;
        protected Decimal mspace;
        protected TabGroupBase mparent;
        protected TabbedGroups mtabbedGroups;
	
		#region Constructors
		
		protected TabGroupBase(TabbedGroups tabbedGroups)
        {
            InternalConstruct(tabbedGroups, null);
        }
        
        protected TabGroupBase(TabbedGroups tabbedGroups, TabGroupBase parent)
		{
		    InternalConstruct(tabbedGroups, parent);
		}
		
		protected void InternalConstruct(TabbedGroups tabbedGroups, TabGroupBase parent)
		{
		    mtabbedGroups = tabbedGroups;
		    mparent = parent;
		    munique = mcount++;
		    
		    mtag = null;
		    mspace = 100m;
		    mminSize = new Size(mtabbedGroups.DefaultGroupMinimumWidth,
		                        mtabbedGroups.DefaultGroupMinimumHeight);
		}

		#endregion

		#region Abstracts

		public abstract void Dispose();

		public abstract int Count               { get; }
		public abstract bool IsLeaf             { get; }
		public abstract bool IsSequence         { get; }
		public abstract Control GrouparamControl    { get; }
        
		public abstract void Notify(NotifyCode code); 
		public abstract bool ContainsProminent(bool recurse);
		public abstract void SaveToXml(XmlTextWriter xmlOut);
		public abstract void LoadFromXml(XmlTextReader xmlIn);

		#endregion
		
		#region Properties
		
		public TabbedGroups TabbedGroups 
		{
			get { return mtabbedGroups; }
		}

		public object Tag
		{
			get { return mtag; }
			set { mtag = value; }
		}
        
		public int Unique
		{
			get { return munique; }
		}

		public Decimal Space
        {
            get 
            {
                TabGroupLeaf prominent = mtabbedGroups.ProminentLeaf;
                
                if (prominent != null)
                {
                    if (mparent.Parent == null)
                    {
                        if (this.ContainsProminent(true))
                            return 100m;
                        else
                            return 0m;
                    }
                    else
                    {
                        if (mparent.ContainsProminent(true))
                        {
                            if (this.ContainsProminent(true))
                                return 100m;
                            else
                                return 0m;
                        }
                        else
                        {
                            return mspace;                        
                        }
                    }
                }
                else
                    return mspace; 
            }
            
            set { mspace = value; }
        }

        internal Decimal RealSpace
        {
            get { return mspace; }
            set { mspace = value; }
        }

        public Size MinimumSize
        {
            get { return mminSize; }
            
            set
            {
                if (!mminSize.Equals(value))
                {
                    mminSize = value;
                    
                    if (mparent != null)
                        mparent.Notify(NotifyCode.MinimumSizeChanged);
                }
            }
        }

        public TabGroupBase Parent 
        {
            get { return mparent; }
        }

		#endregion

		#region Methods

        internal void SetParent(TabGroupBase tgb)
        {
            mparent = tgb;
        }

		#endregion
    }
}
